package server;

import java.io.*;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

//服务器只有一个
//启动服务器之后是不能停掉的
//如果来了一个浏览器访问，需要启动一个服务器线程去处理当前浏览器的请求与响应
//服务器等待下一个浏览器
public class Handler extends Thread{

    //为了让每一个Controller对象是单例的
    //服务器内写一个管理对象的容器，map<String,HttpServlet>
    private Map<String,HttpServlet> controllerMap = new HashMap<>();
    //将socket当作服务器的属性来存储
    private Socket socket;

    public Handler(Socket socket){
        this.socket = socket;
    }

    public void run(){
        this.receiveRequest();
    }

    //接受浏览器发送的请求数据
    private void receiveRequest(){
        try {
            //创建一个用来读取信息的输入流
            InputStream inputStream = socket.getInputStream();
            //将字节流转换成字符流
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            //将字符流包装成Buffered缓冲流
            BufferedReader reader = new BufferedReader(inputStreamReader);
            //读取浏览器发送的一行请求数据
            String content = reader.readLine();//真正读的位置
            this.parseContent(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //解析请求
    private void parseContent(String content){
        String[] s = content.split(" ");
        if (s.length > 1){
            content = s[1].substring(1);
        }
        //提前创建好两个空的容器
        String requestName = null;
        Map<String,String> parameterMap = null;
        //开始解析
        int index = content.indexOf("?");//找到？出现的位置
        if(index != -1){//有参数
            requestName = content.substring(0,index);//请求名字
            parameterMap = new HashMap<>();//懒加载
            //获取后半部分
            String allKeyAndValues = content.substring(index + 1);
            String[] keyAndValues = allKeyAndValues.split("&");
            for (String keyAndValue : keyAndValues){
                String[] kv = keyAndValue.split("=");
                parameterMap.put(kv[0],kv[1]);
            }
        }else {//没有参数
            requestName = content;
        }
        HttpServletRequest request = new HttpServletRequest(requestName, parameterMap);
        HttpServletResponse response = new HttpServletResponse();
        this.findServlet(request,response);
    }

    //请求名字。寻找资源(文件/操作)
    private void findServlet(HttpServletRequest request,HttpServletResponse response){
        try {
            //获取request对象中的请求名
            String requestName = request.getRequestName();
            //通过请求名字找寻对应的Controller对象
            HttpServlet servlet = controllerMap.get(requestName);
            //让对象做事
            if (servlet == null){
                //根据请求的名字，找类全名，反射创建对象，对象存入map集合中
                String className = MyServerReader.getValue(requestName);
                //通过类名字反射加载类
                Class<?> clazz = Class.forName(className);
                //通过class创建对象
                servlet = (HttpServlet) clazz.newInstance();
                controllerMap.put(requestName,servlet);
            }
            //直接调方法
            /*servlet.service(request);*/
            //通过反射调方法
            Class clazz = servlet.getClass();
            Method method = clazz.getMethod("service", HttpServletRequest.class,HttpServletResponse.class);
            method.invoke(servlet,request,response);
            responseToBrowser(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void responseToBrowser(HttpServletResponse response){
        String responseContent = response.getResponseContent();
        try {
            OutputStream outputStream = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(outputStream);
            writer.println(responseContent);//响应会浏览器
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
